package com.macro.mall.service.impl;

import cn.hutool.core.date.DateUtil;
import com.macro.mall.common.service.RedisService;
import com.macro.mall.dao.DashboardDao;
import com.macro.mall.dto.DashboardOrderChartDTO;
import com.macro.mall.dto.DashboardStatisticsDTO;
import com.macro.mall.service.DashboardService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 仪表盘统计Service实现类
 * Created by macro on 2023/6/15.
 */
@Service
public class DashboardServiceImpl implements DashboardService {
    private static final Logger LOGGER = LoggerFactory.getLogger(DashboardServiceImpl.class);
    
    @Value("${redis.database}")
    private String redisDatabase;
    @Value("${redis.expire.common}")
    private Long redisExpire;
    
    @Autowired
    private DashboardDao dashboardDao;
    @Autowired
    private RedisService redisService;

    @Override
    public Map<String, Object> getStatistics() {
        String key = redisDatabase + ":dashboard:statistics";
        // 尝试从缓存中获取
        Map<String, Object> result = (Map<String, Object>) redisService.get(key);
        if (result != null) {
            return result;
        }

        // 如果缓存中没有，重新计算
        DashboardStatisticsDTO statisticsDTO = new DashboardStatisticsDTO();
        // 设置总体统计信息
        DashboardStatisticsDTO.TotalStatistics totalStatistics = new DashboardStatisticsDTO.TotalStatistics();
        totalStatistics.setTodayOrderCount(dashboardDao.getTodayOrderCount());
        totalStatistics.setTodaySalesAmount(new BigDecimal(dashboardDao.getTodaySalesAmount().get("sales_amount").toString()));
        totalStatistics.setYesterdaySalesAmount(new BigDecimal(dashboardDao.getYesterdaySalesAmount().get("sales_amount").toString()));
        statisticsDTO.setTotalStatistics(totalStatistics);

        // 设置待处理事务
        DashboardStatisticsDTO.PendingTasks pendingTasks = new DashboardStatisticsDTO.PendingTasks();
        pendingTasks.setUnpaidOrderCount(dashboardDao.getOrderCountByStatus(0)); // 待付款
        pendingTasks.setCompletedOrderCount(dashboardDao.getOrderCountByStatus(3)); // 已完成
        pendingTasks.setPendingReceiveOrderCount(dashboardDao.getOrderCountByStatus(2)); // 待收货
        pendingTasks.setPendingDeliveryOrderCount(dashboardDao.getOrderCountByStatus(1)); // 待发货
        pendingTasks.setNewOutOfStockCount(dashboardDao.getLowStockProductCount(10)); // 库存<10的商品
        pendingTasks.setPendingRefundCount(dashboardDao.getReturnApplyCount(0)); // 待处理退款
        pendingTasks.setDeliveredOrderCount(dashboardDao.getOrderCountByStatus(2)); // 已发货
        pendingTasks.setPendingReturnCount(dashboardDao.getReturnApplyCount(1)); // 待处理退货
        pendingTasks.setExpiringAdsCount(10); // 假设10个即将到期广告
        statisticsDTO.setPendingTasks(pendingTasks);

        // 设置商品概览
        DashboardStatisticsDTO.ProductOverview productOverview = new DashboardStatisticsDTO.ProductOverview();
        productOverview.setOffShelfCount(dashboardDao.getProductCount(0, null)); // 已下架商品
        productOverview.setOnShelfCount(dashboardDao.getProductCount(1, null)); // 已上架商品
        productOverview.setLowStockCount(dashboardDao.getLowStockProductCount(20)); // 库存紧张商品
        productOverview.setTotalCount(dashboardDao.getProductCount(null, null)); // 商品总数
        statisticsDTO.setProductOverview(productOverview);

        // 设置用户概览
        DashboardStatisticsDTO.UserOverview userOverview = new DashboardStatisticsDTO.UserOverview();
        userOverview.setTodayNewCount(dashboardDao.getUserCount(DateUtil.beginOfDay(new Date()), DateUtil.endOfDay(new Date())));
        userOverview.setYesterdayNewCount(dashboardDao.getUserCount(DateUtil.beginOfDay(DateUtil.yesterday()), DateUtil.endOfDay(DateUtil.yesterday())));
        userOverview.setMonthNewCount(dashboardDao.getUserCount(DateUtil.beginOfMonth(new Date()), DateUtil.endOfMonth(new Date())));
        userOverview.setTotalCount(dashboardDao.getUserCount(null, null));
        statisticsDTO.setUserOverview(userOverview);

        // 设置订单统计
        DashboardStatisticsDTO.OrderStatistics orderStatistics = new DashboardStatisticsDTO.OrderStatistics();
        // 本月
        Date monthBegin = DateUtil.beginOfMonth(new Date());
        Date monthEnd = DateUtil.endOfMonth(new Date());
        Integer currentMonthOrderCount = dashboardDao.getOrderCount(monthBegin, monthEnd);
        BigDecimal currentMonthSalesAmount = new BigDecimal(dashboardDao.getOrderSalesAmount(monthBegin, monthEnd).get("sales_amount").toString());
        orderStatistics.setMonthOrderCount(currentMonthOrderCount);
        orderStatistics.setMonthSalesAmount(currentMonthSalesAmount);
        
        // 上月
        Calendar lastMonth = Calendar.getInstance();
        lastMonth.add(Calendar.MONTH, -1);
        Date lastMonthBegin = DateUtil.beginOfMonth(lastMonth.getTime());
        Date lastMonthEnd = DateUtil.endOfMonth(lastMonth.getTime());
        Integer lastMonthOrderCount = dashboardDao.getOrderCount(lastMonthBegin, lastMonthEnd);
        BigDecimal lastMonthSalesAmount = new BigDecimal(dashboardDao.getOrderSalesAmount(lastMonthBegin, lastMonthEnd).get("sales_amount").toString());
        
        // 计算同比增长率
        orderStatistics.setMonthOrderCountGrowth(calculateGrowthRate(currentMonthOrderCount, lastMonthOrderCount));
        orderStatistics.setMonthSalesAmountGrowth(calculateGrowthRate(currentMonthSalesAmount, lastMonthSalesAmount));
        
        // 本周
        Date weekBegin = DateUtil.beginOfWeek(new Date());
        Date weekEnd = DateUtil.endOfWeek(new Date());
        Integer currentWeekOrderCount = dashboardDao.getOrderCount(weekBegin, weekEnd);
        BigDecimal currentWeekSalesAmount = new BigDecimal(dashboardDao.getOrderSalesAmount(weekBegin, weekEnd).get("sales_amount").toString());
        orderStatistics.setWeekOrderCount(currentWeekOrderCount);
        orderStatistics.setWeekSalesAmount(currentWeekSalesAmount);
        
        // 上周
        Calendar lastWeek = Calendar.getInstance();
        lastWeek.add(Calendar.WEEK_OF_YEAR, -1);
        Date lastWeekBegin = DateUtil.beginOfWeek(lastWeek.getTime());
        Date lastWeekEnd = DateUtil.endOfWeek(lastWeek.getTime());
        Integer lastWeekOrderCount = dashboardDao.getOrderCount(lastWeekBegin, lastWeekEnd);
        BigDecimal lastWeekSalesAmount = new BigDecimal(dashboardDao.getOrderSalesAmount(lastWeekBegin, lastWeekEnd).get("sales_amount").toString());
        
        // 计算环比增长率
        orderStatistics.setWeekOrderCountGrowth(calculateGrowthRate(currentWeekOrderCount, lastWeekOrderCount));
        orderStatistics.setWeekSalesAmountGrowth(calculateGrowthRate(currentWeekSalesAmount, lastWeekSalesAmount));
        
        statisticsDTO.setOrderStatistics(orderStatistics);

        result = new HashMap<>();
        result.put("totalStatistics", totalStatistics);
        result.put("pendingTasks", pendingTasks);
        result.put("productOverview", productOverview);
        result.put("userOverview", userOverview);
        result.put("orderStatistics", orderStatistics);

        // 将结果存入缓存，设置过期时间为1小时
        redisService.set(key, result, redisExpire);
        
        return result;
    }

    @Override
    public Map<String, Object> getOrderChart(Date startDate, Date endDate) {
        String key = redisDatabase + ":dashboard:orderChart";
        if (startDate != null && endDate != null) {
            key += ":" + DateUtil.format(startDate, "yyyyMMdd") + "-" + DateUtil.format(endDate, "yyyyMMdd");
        }
        
        // 尝试从缓存中获取
        Map<String, Object> result = (Map<String, Object>) redisService.get(key);
        if (result != null) {
            return result;
        }
        
        // 如果未指定日期范围，默认获取最近7天的数据
        if (startDate == null || endDate == null) {
            endDate = new Date();
            startDate = DateUtil.offsetDay(endDate, -6);
        }
        
        // 获取订单图表数据
        List<DashboardOrderChartDTO.OrderChartData> orderChartData = dashboardDao.getOrderChartData(startDate, endDate);
        
        // 创建返回结果
        DashboardOrderChartDTO orderChartDTO = new DashboardOrderChartDTO();
        List<String> columns = Arrays.asList("date", "orderCount", "orderAmount");
        orderChartDTO.setColumns(columns);
        orderChartDTO.setRows(orderChartData);
        
        result = new HashMap<>();
        result.put("columns", columns);
        result.put("rows", orderChartData);
        
        // 将结果存入缓存，设置过期时间为1小时
        redisService.set(key, result, redisExpire);
        
        return result;
    }
    
    @Override
    public void refreshStatistics() {
        LOGGER.info("开始刷新仪表盘统计数据缓存");
        
        // 删除统计数据缓存
        String statisticsKey = redisDatabase + ":dashboard:statistics";
        redisService.del(statisticsKey);
        
        // 删除订单图表数据缓存，这里使用模式匹配删除所有相关缓存
        String orderChartKeyPattern = redisDatabase + ":dashboard:orderChart*";
        // 注意：这里假设RedisService有一个方法可以根据模式删除键
        // 如果没有这样的方法，需要先获取所有匹配的键，然后逐个删除
        List<String> keys = new ArrayList<>();
        keys.add(redisDatabase + ":dashboard:orderChart");
        redisService.del(keys);
        
        LOGGER.info("仪表盘统计数据缓存刷新完成");
    }
    
    /**
     * 计算增长率
     */
    private Integer calculateGrowthRate(Number current, Number previous) {
        if (previous == null || previous.doubleValue() == 0) {
            return 0;
        }
        double growth = (current.doubleValue() - previous.doubleValue()) / previous.doubleValue() * 100;
        return (int) growth;
    }
} 